package fr.vod.ihm.adapter;

import java.security.interfaces.DSAKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import fr.vod.videoshareucp.R;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

	// / tag des logs
	//private final static String logTag = ExpandableListAdapter.class.getName();
	
	private final static String HEADER_DEVICES = "Devices";
	private final static String HEADER_QUALITY = "Quality";
	private final static String HEADER_HEARTBEAT_LOGS = "Heartbeat Logs";
	private final static String HEADER_SYNCHRO_LOGS = "Synchro Logs";

	private Context _context;
	private List<String> _listDataHeader; // header titles
	// child data in format of header title, child title
	private HashMap<String, List<String>> _listDataChild;

	// / donnees a mettre dans la liste
	private Map<String, Boolean> data;
	// / cle de la map sous forme d'ArrayList
	private ArrayList<String> keysArray = new ArrayList<String>();

	private String _deviceName;
	private String _ipString;

	private StringBuilder _heartbeatLog;
	private StringBuilder _synchroLog;
	private boolean heartbeatLog = false;
	private boolean syncLog = false;
	private boolean isServer = false;

	public ExpandableListAdapter(Context context, String deviceName, String ipString, boolean heartbeatLog, boolean syncLog) {
		this._context = context;
		this._deviceName = deviceName;
		this._ipString = ipString;
		this.heartbeatLog = heartbeatLog;
		this.syncLog = syncLog;
		prepareListHeaders();
		
	}

	@Override
	public Object getChild(int groupPosition, int childPosititon) {
		//LogHelper.entree(logTag, "getChild");
		return this._listDataChild.get(this._listDataHeader.get(groupPosition))
				.get(childPosititon);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		//LogHelper.entree(logTag, "getChildId");
		return childPosition;
	}

	@Override
	public View getChildView(int groupPosition, final int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		//LogHelper.entree(logTag, "getChildView");

		String childText = null;
		
		if (groupPosition != 0 && groupPosition != 2 && groupPosition != 3) {
			childText = (String) getChild(groupPosition, childPosition);
		}

		if (convertView == null) {
		}

		// instantiation de l'inflateur
		LayoutInflater infalInflater = (LayoutInflater) this._context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		switch (groupPosition) {
		case 0:

			switch (childPosition) {
			case 0:
				TextView subtitleText1;
				convertView = infalInflater.inflate(R.layout.device_subtitle, null);
				subtitleText1 = (TextView) convertView.findViewById(R.id.subtitleText);
				subtitleText1.setText("My Device");
				break;
			case 1:
				// My Device
				TextView myDevice;
				TextView myDeviceName;
				convertView = infalInflater.inflate(R.layout.quality_speed, null);
				myDevice = (TextView) convertView.findViewById(R.id.speedTextView);
				myDevice.setText("My Device : ");
				myDeviceName = (TextView) convertView.findViewById(R.id.speedText);
				myDeviceName.setText(this._deviceName);
				break;
			case 2:
				// My IP
				TextView myIp;
				TextView myIpString;
				convertView = infalInflater.inflate(R.layout.quality_speed, null);
				myIp = (TextView) convertView.findViewById(R.id.speedTextView);
				myIp.setText("My IP : ");
				myIpString = (TextView) convertView.findViewById(R.id.speedText);
				myIpString.setText(this._ipString);
				break;
			case 3:
				TextView subtitleText2;
				convertView = infalInflater.inflate(R.layout.device_subtitle, null);
				subtitleText2 = (TextView) convertView.findViewById(R.id.subtitleText);
				subtitleText2.setText("Other Devices");
				break;
			default:
				// url testee
				String key = keysArray.get(childPosition-4);
				// recuperation de la valeur du flag pour savoir quel layout
				// instancier et quel TextView trouver
				boolean flag = data.get(key);
				
				TextView ipDevice;
				// en fonction du flag le textView vert ou rouge est instantier
				if (true == flag) {
					convertView = infalInflater.inflate(R.layout.device_available, null);
					ipDevice = (TextView) convertView.findViewById(R.id.contactable);
				} else {
					convertView = infalInflater.inflate(R.layout.device_unavailable, null);
					ipDevice = (TextView) convertView.findViewById(R.id.absencereponse);
				}
				ipDevice.setText(key);
				break;
			}
			break;
		case 1:
			TextView progressText;
			TextView speedTextView;
			TextView speedText;
			
			switch (childPosition) {
			case 0:
				String fileSize = _listDataChild.get("Quality").get(0);
				convertView = infalInflater.inflate(R.layout.quality_speed, null);
				speedTextView = (TextView) convertView.findViewById(R.id.speedTextView);
				speedTextView.setText("Size : ");
				speedText = (TextView) convertView.findViewById(R.id.speedText);
				speedText.setText(fileSize);
				break;
			case 1:
				String initTimestamp = _listDataChild.get("Quality").get(1);
				convertView = infalInflater.inflate(R.layout.quality_speed, null);
				speedTextView = (TextView) convertView.findViewById(R.id.speedTextView);
				speedTextView.setText("Start time : ");
				speedText = (TextView) convertView.findViewById(R.id.speedText);
				speedText.setText(initTimestamp);
				break;
			case 2:
					convertView = infalInflater.inflate(R.layout.quality_speed, null);
					speedTextView = (TextView) convertView.findViewById(R.id.speedTextView);
					speedText = (TextView) convertView.findViewById(R.id.speedText);
					if (!isServer) {
						String downloadSpeed = _listDataChild.get("Quality").get(2);
						speedTextView.setText("Download : ");
						Double ret = Double.valueOf(downloadSpeed);
						ret = Math.round(ret * 100.0) / 100.0;
						speedText.setText(ret + " ko/s");
					} else {
						speedTextView.setText("");
						speedText.setText("");
					}
				break;
			case 3:
					convertView = infalInflater.inflate(R.layout.quality_speed, null);
					speedTextView = (TextView) convertView.findViewById(R.id.speedTextView);
					speedText = (TextView) convertView.findViewById(R.id.speedText);
					if (isServer) {
						String uploadSpeed = _listDataChild.get("Quality").get(3);
						speedTextView.setText("Upload : ");
						Double ret = Double.valueOf(uploadSpeed);
						ret = Math.round(ret*100.0) / 100.0;
						speedText.setText(ret + " ko/s");
					} else {
						speedTextView.setText("");
						speedText.setText("");
					}
				break;
			case 4:
				if (!isServer) {
					convertView = infalInflater.inflate(R.layout.quality_speed, null);
					speedTextView = (TextView) convertView.findViewById(R.id.speedTextView);
					speedText = (TextView) convertView.findViewById(R.id.speedText);
					if (!isServer) {
						String etaTransfert = _listDataChild.get("Quality").get(4);
						if (!etaTransfert.isEmpty()) {
						speedTextView.setText("ETA : ");
						int etaTimeSeconds = Integer.parseInt(etaTransfert);
						String test = String.format("%d h %02d m %02d s", etaTimeSeconds/3600, (etaTimeSeconds%3600)/60, (etaTimeSeconds%60));
						speedText.setText(test + " seconds");
						}
					} else {
						speedTextView.setText("");
						speedText.setText("");
					}
				}
				break;
			case 5:
				int key2 = Integer.valueOf(_listDataChild.get("Quality").get(5));
				convertView = infalInflater.inflate(R.layout.quality_progress_bar, null);
				
				ProgressBar mProgress = (ProgressBar) convertView.findViewById(R.id.progressBar);
				mProgress.setProgress(key2);
				mProgress.setProgressDrawable(_context.getResources().getDrawable(R.drawable.my_progress_bar));
				
				progressText = (TextView) convertView.findViewById(R.id.progressText);
				progressText.setText(key2 + " %");
				
				break;
			default:
				convertView = infalInflater.inflate(R.layout.list_item, null);
				progressText = (TextView) convertView
						.findViewById(R.id.lblListItem);
				progressText.setText(childText);
				break;
			}
			break;
		case 2:
		case 3:
			convertView = infalInflater.inflate(R.layout.logs_scrollview, null);
			ScrollView scrollView = (ScrollView) convertView.findViewById(R.id.scrollViewLog);
			TextView txtScrollView = (TextView) convertView.findViewById(R.id.textViewLog);
			if (groupPosition == 2)
				txtScrollView.setText(_heartbeatLog.toString());
			else 
				txtScrollView.setText(_synchroLog.toString());
			scrollView.fullScroll(ScrollView.FOCUS_DOWN);
			break;
		default:
			break;
		}
		return convertView;
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		//LogHelper.entree(logTag, "getChildrenCount");
		if (groupPosition == 0) {
			if (this.keysArray.size() == 0)
				return 3;
			else
				return 4 + this.keysArray.size();
		}
		else if (groupPosition == 2) { // log heartbeat
			if (heartbeatLog)
				return 1;
			else
				return 0;
		}
		else if (groupPosition == 3) { // log synchro video
			if (syncLog)
				return 1;
			else
				return 0;
		}
		else
			return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
	}

	@Override
	public Object getGroup(int groupPosition) {
		return this._listDataHeader.get(groupPosition);
	}

	@Override
	public int getGroupCount() {
		return this._listDataHeader.size();
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		String headerTitle = (String) getGroup(groupPosition);
		if (convertView == null) {
			LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = infalInflater.inflate(R.layout.list_group, null);
		}

		TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
		lblListHeader.setTypeface(null, Typeface.BOLD);
		lblListHeader.setText(headerTitle);

		return convertView;
	}

	@Override
	public boolean hasStableIds() {
		return false;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true;
	}
	
	public void setAvailableDevicesKeys(HashMap<String, Boolean> availableDevices) {
		Set<String> keys = availableDevices.keySet();
		this.data = availableDevices;
		keysArray = new  ArrayList<String>(keys);
		this.notifyDataSetChanged();
	}
	
	public void updateFileSize(String filesize) {
		_listDataChild.get(_listDataHeader.get(1)).set(0, filesize);
	}

	public void updateInitTimestamp(String timestamp) {
		_listDataChild.get(_listDataHeader.get(1)).set(1, timestamp);
	}
	
	public void updateDownloadSpeed(String speed) {
		_listDataChild.get(_listDataHeader.get(1)).set(2, speed);
	}
	
	public void updateUploadSpeed(String speed) {
		_listDataChild.get(_listDataHeader.get(1)).set(3, speed);
	}
	
	public void updateEtaTime(String eta) {
		_listDataChild.get(_listDataHeader.get(1)).set(4, eta);
		this.notifyDataSetChanged();
	}
	
	public void updateProgressBar(String progress) {
		_listDataChild.get(_listDataHeader.get(1)).set(5, progress);
	}
	
	public void appendToHeartbeatLog(String text) {
		if (heartbeatLog) {
			_heartbeatLog.append(text + "\n");
			this.notifyDataSetChanged();
		}
	}
	
	public void appendToSynchroLog(String text) {
		if (syncLog) {
			_synchroLog.append(text + "\n");
			this.notifyDataSetChanged();
		}
	}
	
	public void myDataSetChanged() {
		this.notifyDataSetChanged();
	}
	
	public void prepareListHeaders() {
		_listDataHeader = new ArrayList<String>();
        _listDataChild = new HashMap<String, List<String>>();
 
        // Adding child data
        _listDataHeader.add(HEADER_DEVICES);
        _listDataHeader.add(HEADER_QUALITY);
        
        if (heartbeatLog) {
        	_listDataHeader.add(HEADER_HEARTBEAT_LOGS);
        	_heartbeatLog = new StringBuilder();
        }
        if (syncLog) {
        	_listDataHeader.add(HEADER_SYNCHRO_LOGS);
        	_synchroLog = new StringBuilder();
        }
        List<String> quality = new ArrayList<String>();
        quality.add("Not received yet"); // filesize
        quality.add(""); // init timestamp
        quality.add("0"); // download speed
        quality.add("0"); // upload speed
        quality.add(""); // remaining time
        quality.add("0"); // progress
        
        _listDataChild.put(_listDataHeader.get(1), quality);
	}

	public void setIsServer(boolean isServer) {
		this.isServer = isServer;
	}

}
